/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package assisisw.smartcal.entitysubsystem;

import assisisw.smartcal.notificationsubsystem.IEntityControllerObserver;
import assisisw.smartcal.persistencesubsystem.IDAOProvider;
import assisisw.smartcal.utilities.Utilities;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedList;
import java.util.Objects;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;

/**
 *
 * @author Francesco
 */
@Stateless ()
@TransactionManagement ( value = TransactionManagementType.CONTAINER )
public class EventController implements IEventController
{

    // Instance Fields
    
    /***/
    @EJB
    private IDAOProvider daoProvider ;

    /***/
    @EJB
    private IEntityControllerObserver entityControllerObserver ;
    
    // Instance Methods
    
    /***/
    public EventController () {}
    
    /**
     * AS THE SUPER'S ONE.
     */
    @Override
    public Iterable < Event > findByDate ( Date date ) 
    {
        Iterable < Event > all ;
        Collection < Event > res ;
        all = daoProvider.getEventDAO().findAll () ;
        res = new LinkedList <> () ;
        for ( Event e : all )
            if ( Utilities.equalsByDay ( date , e.getIniDate () ) )
                res.add ( e ) ;
        return res ;
    }
    
    /**
     * AS THE SUPER'S ONE.
     */
    @Override
    public void insert ( Event event , Calendar owningCalendar ) 
    {
        Event toInsert ;
        Calendar c ;
        if ( Objects.nonNull ( event ) && Objects.nonNull ( owningCalendar ) )
        {
            c = daoProvider.getCalendarDAO().findById ( owningCalendar.getId () ) ;
            toInsert = new Event ( event.getName () , event.getIniDate () , event.getEndDate () ,event.isOutdoor () , event.getVisibility () , c ) ;
            daoProvider.getEventDAO ().insert ( toInsert ) ;
            event.setOwningCalendar ( owningCalendar ) ;
            event.setId(toInsert.getId()); 
        }
        else
            throw new IllegalArgumentException () ;
    }

    /**
     * AS THE SUPER'S ONE.
     */
    @Override
    public void update ( Event event ) 
    {
        Event toUpdate ;
        toUpdate = daoProvider.getEventDAO().findById(event.getId());
        Event.copySimpleData ( event , toUpdate ) ;
        daoProvider.getEventDAO().update ( toUpdate ) ;
        for ( User u : event.getInvitedUsers() )
            entityControllerObserver.addNotification ( Notification.NotificationType.INVITATION , event, u, "Event " + event.getName () + " updated !" );
    }
    
    /**
     * AS THE SUPER'S ONE.
     */
    @Override
    public void invite ( Event event , User recipient ) 
    {        
        recipient.getInvitedEvents().add(event);
        event.getInvitedUsers().add(recipient);
        daoProvider.getEventDAO().update(event); 
        entityControllerObserver.addNotification(Notification.NotificationType.INVITATION , event , recipient , 
           event.getOwningCalendar().getOwner().getMail() + " has invited you to his event " + event.getName() ) ;
    }
    
    /**
     * AS THE SUPER'S ONE.
     */
    @Override
    public void delete ( Event event ) 
    {
        Event toUpdate ;
        if ( Objects.nonNull ( event ) ) 
        {
            toUpdate = daoProvider.getEventDAO ().findById ( event.getId () ) ;
            daoProvider.getEventDAO ().delete ( toUpdate ) ;
            for ( User u : event.getInvitedUsers() )
                entityControllerObserver.addNotification(Notification.NotificationType.INVITATION, event, u, "Event " + event.getName() + " deleted!");
        }
        else
            throw new IllegalArgumentException () ;
    }    

    @Override
    public void disInvite(Event event, User recipient) 
    {
        event.getInvitedUsers().remove(recipient);
        daoProvider.getEventDAO().update(event); 
        // notify the event owner that the recipient has rejected his invitation
    }
        
}
